package es.udima.geo.geoserver.rest;

import java.util.Collection;
import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import es.udima.geo.geoserver.business.UserController;
import es.udima.geo.geoserver.entities.User;
import es.udima.geo.geoserver.entities.UserUpdateResult;
import es.udima.geo.geoserver.entities.UserUpdateResultError;
import es.udima.geo.geoserver.rest.entities.IResponseError;
import es.udima.geo.geoserver.rest.entities.UserRetrieveError;
import es.udima.geo.geoserver.rest.entities.UserRetrieveResponse;
import es.udima.geo.geoserver.rest.entities.UserUpdateResponse;
import es.udima.geo.geoserver.rest.entities.UsersRetrieveResponse;

/**
 * <p>
 * Servicio de gestión de usuarios para los perfiles de administración del
 * servidor.
 * </p>
 * <p>
 * Este servicio no requiere autentificación de usuario. Se ha implementado sin
 * seguridad porque no era objetivo de este desarrollo hacer un servidor
 * completamente funcional, sino como apoyo a las pruebas de la implementación
 * de los clientes que usan sus servicios.
 * </p>
 * 
 * @author david
 * 
 */
@Path("/admin/users")
public class UserAdminService {

    /**
     * Constructor
     */
    public UserAdminService() {
    }

    /**
     * <p>
     * Recupera de base de datos el usuario con el id de usuario pasado como
     * parámetro.
     * </p>
     * 
     * @param userId
     *            Identificador de usuario por el que se trata de recuperar un
     *            usuario.
     * @return Respuesta de la lectura.
     */
    @GET
    @Path("/{userId}")
    @Produces(MediaType.APPLICATION_JSON)
    public UserRetrieveResponse retrieveUserByUserId(@PathParam("userId") String userId) {
	UserRetrieveResponse res = new UserRetrieveResponse();
	UserController uc = new UserController();
	User user = uc.retrieveUserByUserId(userId);
	if (user == null) {
	    res.addResponseError(UserRetrieveError.USER_NOT_EXISTS);
	} else {
	    res.setUser(user);
	}
	return res;
    }

    /**
     * <p>
     * Recupera de base de datos los usuarios activos.
     * </p>
     * <p>
     * Se entiende como usuarios activos aquellos que no han sido marcados en la
     * tabla de usuarios como inactivos.
     * </p>
     * 
     * @return Respuesta de la lectura.
     */
    @GET
    @Path("/all")
    @Produces(MediaType.APPLICATION_JSON)
    public UsersRetrieveResponse retrieveAllUsers() {
	UsersRetrieveResponse res = new UsersRetrieveResponse();
	try {
	    UserController uc = new UserController();
	    List<User> users = uc.retrieveAllUsers();
	    res.setUsers(users);
	} catch (Exception e) {
	    System.out.println(e.getMessage());
	}
	return res;
    }

    /**
     * <p>
     * Modifica los datos de un usuario en el sistema.
     * </p>
     * <p>
     * <b>ATENCION!</b>Este método no modifica la clave del usuario.
     * </p>
     * 
     * @param user
     *            Usuario que va a ser modificado basándose en el id del usuario
     *            pasado como parámetro.
     * @return Devuelve el resultado de la modificación del usuario. Revisar la
     *         clase devuelta para conocer el tipo de resultados y errores que
     *         pueden darse.
     */
    @POST
    @Path("/update")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public UserUpdateResponse updateUser(User user) {
	UserController uc = new UserController();
	UserUpdateResponse res = new UserUpdateResponse();
	UserUpdateResult ur = uc.updateUser(user);
	if (ur.isUpdateSuccessful()) {
	    res.setUser(ur.getUser());
	} else {
	    res.addResponseErrors(translateUserUpdateErrors(ur.getErrors()));
	}
	return res;
    }

    /*-----------------------------------------------------------------------------------------------*/

    /**
     * <p>
     * Método auxiliar para traducir los errores provenientes del controlador de
     * usuarios a errores de response manejados por los servicios rest.
     * </p>
     * 
     * @param errors
     *            Colección de datos provenientes del controlador de usuarios.
     * @return Colección de errores traducida.
     */
    private Collection<IResponseError> translateUserUpdateErrors(Collection<UserUpdateResultError> errors) {
	return new RestServiceErrorHelper().translateUserUpdateErrors(errors);
    }
}
